/* ========================================================================= */
/* ------------------------------------------------------------------------- */
/*!
  \file			PrpTpl.h
  \date			june 2010
  \author		TNick

  \brief		Contains the definition of PrpTpl class and related


 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 Please read ReadMe.txt and Licence.txt in root folder
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


*/
/* ------------------------------------------------------------------------- */
/* ========================================================================= */
#ifndef __PRPTPL_INC__
#define __PRPTPL_INC__
//
//
//
//
/*  INCLUDES    ------------------------------------------------------------ */


class		PrpMdl;
class		PrpNode;
class		PrpTpl;
class		PrpView;

#include	<QStyleOptionViewItem>
#include	<QVariant>

#include	<generic/cc_l2d.h>


/*  INCLUDES    ============================================================ */
//
//
//
//
/*  CLASS    --------------------------------------------------------------- */

/// class representing the behaviour of an item
/**
*	this class decides the behaviour and general properties of an item.
*/
class PrpTpl : public CC_L2D		{

	//
	//
	//
	//
	/*  DEFINITIONS    --------------------------------------------------------- */

	friend class PrpMdl;
	friend class PrpNode;
public:
	/// various switches
	enum	FLAGS		{
			FNONE		=	0x0000,		/**< no flag is set*/
			FREADONLY	=	0x0001,		/**< the element is read only */
			FROOTITEM	=	0x0002,		/**< the element at the top level */
			FHOST		=	0x0004,		/**< the element may be parent */
			FHASICON	=	0x0008,		/**< some form of icon at left or
			second column */
			FSUBORD		=	0x0010,		/**< this item represents a component
			of it's parent; changes shall go back and forward between
			these two */
			FMAX						/**< for validation purposes */
		};

	/// standard types of items
	enum	TYPE		{
			HEADER = 0,
			BOOLEAN,
			STRING,
			INTEGER,
			DOUBLE,
			COLOR,
			ENUM,

			LN_PATTERN,
			LN_WEIGHT,

			TYMAX		/**< for validation purpose */
		};


	/*  DEFINITIONS    ========================================================= */
	//
	//
	//
	//
	/*  DATA    ---------------------------------------------------------------- */

private:
	/// the type of this item
	TYPE			it_ty;

	/// string used as title for value
	QString			str_name;

	/// string used as description for value
	QString			str_descr;

	union	{
			/// pointer to parent item
			PrpNode*		p_father;
			/// pointer to parent model
			PrpMdl*			p_model;
		};

	/// various flags
	FLAGS			flg;

	/*  DATA    ================================================================ */
	//
	//
	//
	//
	/*  FUNCTIONS    ----------------------------------------------------------- */

public:

	/// constructor;
	PrpTpl		(
			PrpMdl*		pa_mdl,		/**< father model */
			PrpNode*	pa_fth,		/**< father item; NULL for top level */
			TYPE		a_it_ty,	/**< the type for this entry */
			QString		stra_name,	/**< name of entry */
			QString		stra_descr	/**< description of entry */
			);

	/// destructor;
	virtual				~PrpTpl		(void) {}


	/// request actual value in text form
	virtual	QVariant	valAsText	(void) = 0;
	/// request decoration for the value
	virtual	QVariant	valAsDecor	(void) = 0;
	/// request to change the value made by user
	virtual bool		changeVal	(
			QVariant		new_value
			) = 0;
	/// create editor for this type of item
	virtual	QWidget*	editCreate	(
			QWidget *					parent,
			const QStyleOptionViewItem	&option
			) = 0;
	/// load data from item to editor
	virtual	void		editLoad	(
			QWidget *					editor
			) = 0;
	/// save data from editor to item
	virtual	void		editSave	(
			QWidget *					editor
			) = 0;
	/// update geometry for the editor
	virtual	void		editResize	(
			QWidget *					editor,
			const QStyleOptionViewItem	&option
			) { editor->setGeometry(option.rect); }
	/// informed about a click on associated icon
	virtual void		editIcon	(PrpView * prp_v, QModelIndex the_idx)
	{ Q_UNUSED(prp_v); Q_UNUSED(the_idx); }




	/// tell if this element is read-only
	inline bool			isReadOnly	(void)
		{ return ((flg & FREADONLY) != 0); }
	/// sets the read-only state
	inline void			readOnly	(bool ro)
		{
			if (ro == false)	flg = static_cast<FLAGS>(flg & (~FREADONLY));
			else				flg = static_cast<FLAGS>(flg | FREADONLY);
		}


	/// tell if this element is at top level
	inline bool			isTopLevel	(void)
		{ return ((flg & FROOTITEM) != 0); }
	/// sets the top level state
	inline void			topLevel	(bool tl)
		{
			if (tl == false)	flg = static_cast<FLAGS>(flg & (~FROOTITEM));
			else				flg = static_cast<FLAGS>(flg | FROOTITEM);
		}


	/// tell if this element is at top level
	inline bool			isAbleToHost	(void)
		{ return ((flg & FHOST) != 0); }
	/// sets the top level state
	inline void			ableToHost	(bool h)
		{
			if (h == false)		flg = static_cast<FLAGS>(flg & (~FHOST));
			else				flg = static_cast<FLAGS>(flg | FHOST);
		}


	/// tell if this element is stand alone or is subordonate
	inline bool			isInferior	(void)
		{ return ((flg & FSUBORD) != 0); }
	/// sets the stand alone or subordonate state
	inline void			inferior	(bool inf)
		{
			if (inf == false)
				flg = static_cast<FLAGS>(flg & (~FSUBORD));
			else if (!isTopLevel())
				flg = static_cast<FLAGS>(flg | FSUBORD);
			else
				flg = static_cast<FLAGS>(flg & (~FSUBORD));
		}


	/// tell if this element has an associated icon in value column
	inline bool			isIconDec	(void)
		{ return ((flg & FHASICON) != 0); }
	/// sets the top level state
	inline void			iconDec		(bool ic)
		{
			if (ic == false)	flg = static_cast<FLAGS>(flg & (~FHASICON));
			else				flg = static_cast<FLAGS>(flg | FHASICON);
		}


	/// get a pointer to parent item (NULL for top level)
	inline PrpNode*		parent		(void)
		{	if (isTopLevel()) return NULL; return p_father; }
	/// get a pointer to parent model
	PrpMdl*				model		(void);


	/// sets the father item and resets root flag
	inline void			setParent	(PrpNode* pNewFather)
		{ topLevel(false); p_father = pNewFather; }
	/// sets the model and sets root flag
	inline void			setModel	(PrpMdl* pNewFather)
		{ topLevel(true); p_model = pNewFather; }


	/// gets the name of this entry
	inline QString		name		(void)
		{ return str_name; }
	/// sets the name of this entry
	inline void			setName		(QString s_new_name)
		{ str_name = s_new_name; }


	/// gets the description of this entry
	inline QString		description		(void)
		{ return str_descr; }
	/// sets the name of this entry
	inline void			setDescription	(QString s_new_desc)
		{ str_descr = s_new_desc; }



	/// return the index of this item inside parent
	int					row				(void);


	/// gets the type of this entry
	inline TYPE			type			(void)
		{ return it_ty; }
	/// sets the type of this entry
	inline void			setType		(TYPE t_new_name)
		{ it_ty = t_new_name; }



protected:
	/// if the item is subordinate, the function inform the father
	void	informParent	(void);


	/*  FUNCTIONS    =========================================================== */
	//
	//
	//
	//
};	/*	class PrpTpl	*/

/*  CLASS    =============================================================== */
//
//
//
//
/*  CLASS    --------------------------------------------------------------- */

/// class representing an item that may host other items
/**
*
*/
class PrpNode : public PrpTpl		{

	//
	//
	//
	//
	/*  DEFINITIONS    --------------------------------------------------------- */
	friend class PrpMdl;
	friend class PrpTpl;

	/*  DEFINITIONS    ========================================================= */
	//
	//
	//
	//
	/*  DATA    ---------------------------------------------------------------- */

protected:

	/// pointer to first kid
	CC_HDL2D			hd;


	/*  DATA    ================================================================ */
	//
	//
	//
	//
	/*  FUNCTIONS    ----------------------------------------------------------- */

public:

	/// constructor;
	PrpNode		(
			PrpMdl*		pa_mdl,		/**< father model */
			PrpNode*	pa_fth,		/**< father item; NULL for top level */
			TYPE		a_it_ty,	/**< the type for this entry */
			QString		stra_name,	/**< name of entry */
			QString		stra_descr	/**< description of entry */
			) : PrpTpl(pa_mdl,pa_fth,a_it_ty,stra_name,stra_descr)
		{ flg = static_cast<FLAGS>(flg | FHOST); }

	/// destructor;
	virtual				~PrpNode		(void) {}


	/*		easy access to chain of items (forward)	*/

	/// append an item (insert after last)
	inline void			append	(CC_L2D* pIt)
		{ hd.append(pIt); }
	/// get first item
	inline CC_L2D*		first	(void)
		{ return hd.first(); }
	/// get nth item
	inline CC_L2D*		item	(int i)
		{ return hd.item(i); }
	/// get the number of items
	inline int			count	(void)
		{ return hd.count(); }


	/// used by subordonate to inform parent about a change
	virtual	void		subChanged	(PrpTpl* hot_item)
		{Q_UNUSED(hot_item);}

	/// used by parent item to inform inferiors about a change
	virtual	void		updInferiors (void) {}




	/*  FUNCTIONS    =========================================================== */
	//
	//
	//
	//
};	/*	class PrpNode	*/

/*  CLASS    =============================================================== */
//
//
//
//

#endif // __PRPTPL_INC__
/* ------------------------------------------------------------------------- */
/* ========================================================================= */
